package net.sky.oa.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;


import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@SuppressWarnings("serial")
@Entity
@Table(name = "FILE_ATTACH")
@BatchSize(size=15)
public class FileAttach extends BaseModel
{

  protected Long id;
  protected String fileName;
  protected String filePath;
  protected Date createtime;
  protected String ext;
  protected String fileType;
  protected String note;
  protected String creator;//创建人
  protected Integer status; //状态: 1 为正常   2为文件所有者已删除
  
  private Integer ispublic;//文件是否共享  1为不共享 2为共享
  private DocFolder docFolder;
  private SysEmployee user;//所属用户
  private Set<SysEmployee> fusers; //Favorite User文件收藏
  private Set<DocFileUser> docFileUsers;  //文件发送
  
  public FileAttach()
  {
  }

  public FileAttach(Long in_fileId)
  {
    setId(in_fileId);
  }
  
  
  
  /**
 * @param id
 * @param fileName
 * @param filePath
 * @param createtime
 * @param ext
 * @param fileType
 * @param note
 * @param creator
 * @param status
 * @param ispublic
 */
public FileAttach(Long id, String fileName, String filePath, Date createtime,
		String ext, String fileType, String note, String creator,
		Integer status, Integer ispublic) {
	super();
	this.id = id;
	this.fileName = fileName;
	this.filePath = filePath;
	this.createtime = createtime;
	this.ext = ext;
	this.fileType = fileType;
	this.note = note;
	this.creator = creator;
	this.status = status;
	this.ispublic = ispublic;
}

@Id
  @SequenceGenerator(name="SQ_FILEATTACH_ID",sequenceName="SQ_FILEATTACH_ID",allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="SQ_FILEATTACH_ID")
  @Column(name = "ID", unique = true, nullable = false)
  public Long getId() {
	  return id;
  }
  
  public void setId(Long id) {
	  this.id = id;
  }

  @Column(name = "FILE_NAME", length = 130)
  public String getFileName()
  {
    return this.fileName;
  }


public void setFileName(String aValue)
  {
    this.fileName = aValue;
  }
  @Column(name = "FILE_PATH", length = 130)
  public String getFilePath()
  {
    return this.filePath;
  }

  public void setFilePath(String aValue)
  {
    this.filePath = aValue;
  }
  @Temporal(TemporalType.DATE)
  @Column(name = "CREATETIME")
  public Date getCreatetime()
  {
    return this.createtime;
  }

  public void setCreatetime(Date aValue)
  {
    this.createtime = aValue;
  }
  @Column(name = "EXT", length = 40)
  public String getExt()
  {
    return this.ext;
  }

  public void setExt(String aValue)
  {
    this.ext = aValue;
  }
  @Column(name = "FILE_TYPE", length = 40)
  public String getFileType()
  {
    return this.fileType;
  }

  public void setFileType(String aValue)
  {
    this.fileType = aValue;
  }
  
  @Column(name = "NOTE", length = 40)
  public String getNote()
  {
    return this.note;
  }
  public void setNote(String aValue)
  {
    this.note = aValue;
  }
  @Column(name = "CREATOR", length = 40)
  public String getCreator()
  {
    return this.creator;
  }

  public void setCreator(String aValue)
  {
    this.creator = aValue;
  }
  
  @Column(name = "status", length = 2)
	public Integer getStatus() {
		return status;
	}
	
	public void setStatus(Integer status) {
		this.status = status;
	}

public boolean equals(Object object)
  {
    if (!(object instanceof FileAttach)) {
      return false;
    }
    FileAttach rhs = (FileAttach)object;
    return new EqualsBuilder()
      .append(this.id, rhs.id)
      .append(this.fileName, rhs.fileName)
      .append(this.filePath, rhs.filePath)
      .append(this.createtime, rhs.createtime)
      .append(this.ext, rhs.ext)
      .append(this.fileType, rhs.fileType)
      .append(this.note, rhs.note)
      .append(this.creator, rhs.creator)
      .isEquals();
  }

  public int hashCode()
  {
    return new HashCodeBuilder(-82280557, -700257973)
      .append(this.id)
      .append(this.fileName)
      .append(this.filePath)
      .append(this.createtime)
      .append(this.ext)
      .append(this.fileType)
      .append(this.note)
      .append(this.creator)
      .toHashCode();
  }

  public String toString()
  {
    return new ToStringBuilder(this)
      .append("fileId", this.id)
      .append("fileName", this.fileName)
      .append("filePath", this.filePath)
      .append("createtime", this.createtime)
      .append("ext", this.ext)
      .append("type", this.fileType)
      .append("note", this.note)
      .append("creator", this.creator)
      .toString();
  }
  
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "FOLDER_ID")
  public DocFolder getDocFolder() {
		return docFolder;
  }
	
  public void setDocFolder(DocFolder docFolder) {
		this.docFolder = docFolder;
  }
  
  @Column(name = "ISPUBLIC", precision = 2, scale = 0)
   public Integer getIspublic() {
	  return ispublic;
  }

	public void setIspublic(Integer ispublic) {
		this.ispublic = ispublic;
	}
	
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "USER_ID")
  public SysEmployee getUser() {
	return user;
  }


public void setUser(SysEmployee user) {
	  this.user = user;
  }

  @ManyToMany(fetch=FetchType.EAGER)
  @JoinTable(name="file_user",joinColumns={@JoinColumn(name="file_id")},inverseJoinColumns={@JoinColumn(name="user_id")})  
  @Cascade(value={CascadeType.PERSIST,CascadeType.MERGE}) 
  public Set<SysEmployee> getFusers() {
	  return fusers;
  }
  public void setFusers(Set<SysEmployee> fusers) {
		this.fusers = fusers;
  }
  @OneToMany(fetch=FetchType.EAGER,mappedBy="file")
  @Cascade(value={CascadeType.SAVE_UPDATE,CascadeType.DELETE_ORPHAN}) 
  public Set<DocFileUser> getDocFileUsers() {
		return docFileUsers;
  }
  public void setDocFileUsers(Set<DocFileUser> docFileUsers) {
		this.docFileUsers = docFileUsers;
  }
  
  /**
	 * 作用：
	 * 1、把原来选中现在选中的保留
	 * 2、把原来选中现在没有选中的删除掉
	 * 3、把原来没有选中现在选中的增加进去
	 * @param checkedIds
	 */
	@Transient
	public void mergeByCheckedIds(int type,SysEmployee suser,final Collection<Long> checkedIds) {
		Set<DocFileUser> docFileUsers = this.getDocFileUsers();
		if(docFileUsers == null){
			docFileUsers = new HashSet<DocFileUser>();
		}
		if(type==1){
			if (checkedIds == null) {//如果checkedIds为空,则去掉所有发送用户不为空的记录
				for(DocFileUser element:docFileUsers)
				{
					if(1==element.getIsforward()){
						docFileUsers.remove(element);
					}
				}
				return;
			}
			else
			{
				Set<Long> set=new HashSet<Long>();
				List<Long> list=new ArrayList<Long>();
				for(Iterator<Long> iter=checkedIds.iterator();iter.hasNext();){
					Long id=iter.next();
					if(set.add(id)){
						list.add(id);
					}
				}
				checkedIds.clear();
				checkedIds.addAll(list);//去除checkedIds中的重复记录
			}
			Iterator<DocFileUser> it = docFileUsers.iterator();
			while (it.hasNext()) {
				DocFileUser element = it.next();
				if(1==element.getIsforward()){
					Long id = element.getRusr().getId();
					if (!checkedIds.contains(id)) {
						it.remove();
					} else {
						checkedIds.remove(id);
					}
				}
			}
		}
		if(type==2){//如果checkedIds为空,则去掉所有转发用户不为空的记录
			if (checkedIds == null) {
				for(DocFileUser element:docFileUsers)
				{
					if(2==element.getIsforward()){//移出所有用户
						docFileUsers.remove(element);
					}
				}
				return;
			}
			else
			{
				Set<Long> set=new HashSet<Long>();
				List<Long> list=new ArrayList<Long>();
				for(Iterator<Long> iter=checkedIds.iterator();iter.hasNext();){
					Long id=iter.next();
					if(set.add(id)){
						list.add(id);
					}
				}
				checkedIds.clear();
				checkedIds.addAll(list);//去除checkedIds中的重复记录
			}
			Iterator<DocFileUser> it = docFileUsers.iterator();
			while (it.hasNext()) {
				DocFileUser element = it.next();
				if(null!=element.getFusr()){//判断转发用户与登陆用户一致
					if(2==element.getIsforward()&&suser.getId().equals(element.getFusr().getId())){
						Long id = element.getRusr().getId();
						if (!checkedIds.contains(id)) {
							it.remove();
						} else {
							checkedIds.remove(id);
						}
					}
				}
			}
		}
		
		for (Long id : checkedIds) {
			DocFileUser docFileUser = new DocFileUser();
			SysEmployee user = new SysEmployee();
			user.setId(id);		
			if(type==1){//文件发送
				docFileUser.setSusr(suser);
				docFileUser.setRusr(user);
				docFileUser.setIsforward(1);
			}else if(type==2)//文件转发
			{
				docFileUser.setFusr(suser);
				docFileUser.setRusr(user);
				docFileUser.setIsforward(2);
			}
			docFileUser.setFile(this);
			docFileUser.setIsrecieve(1);//未查收
			docFileUser.setSendtime(new Date());
			docFileUsers.add(docFileUser);
		}
		this.setDocFileUsers(docFileUsers);
		
	}
}